package com.jg.poiet.word;

import com.itextpdf.text.*;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.jg.poiet.exception.WordException;
import org.apache.poi.xddf.usermodel.text.TabAlignment;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XWPFNiceWord extends NiceWord {

    private static BaseFont PDF_FONT = null;

    static {
        try {
            PDF_FONT = BaseFont.createFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception ignore) {
        }
    }

    private XWPFDocument document;

    public XWPFNiceWord(XWPFDocument document) {
        this.document = document;
    }

    @Override
    public void writeToPdfFile(String path) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(path);
            com.itextpdf.text.Document pdfDoc = new Document();
            PdfWriter writer = PdfWriter.getInstance(pdfDoc, fos);
            pdfDoc.open();
            Map<Integer, Integer> listIndexMap = new HashMap<>();
            for (IBodyElement element : document.getBodyElements()) {
                for (Element pdfEle : buildPdfElement(element, listIndexMap)) {
                    pdfDoc.add(pdfEle);
                }
            }
            pdfDoc.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new WordException("word转pdf失败！");
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception ignore) { }
        }
    }

    private List<Element> buildPdfElement(IBodyElement element, Map<Integer, Integer> listIndexMap) throws IOException, BadElementException {
        List<Element> res = new ArrayList<>();
        if (element instanceof XWPFParagraph) {
            //文字段落
            XWPFParagraph paragraph = (XWPFParagraph) element;
            if (paragraph.getNumID() != null && paragraph.getNumID().intValue() > 0) {
                int numId = paragraph.getNumID().intValue();
                Integer listIndex = listIndexMap.getOrDefault(numId, 0);
                listIndexMap.put(numId, listIndex + 1);
                res.add(buildPdfParagraph(paragraph, listIndexMap.get(numId) + "、"));
            } else {
                res.add(buildPdfParagraph(paragraph));
            }
        } else if (element instanceof XWPFTable) {
            //表格
            XWPFTable table = (XWPFTable) element;
            PdfPTable pdfTable = null;
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                if (pdfTable == null) {
                    pdfTable = new PdfPTable(cells.size());
                    pdfTable.setWidthPercentage(100);
                }
                for (XWPFTableCell cell : cells) {
                    List<IBodyElement> cellElements = cell.getBodyElements();
                    PdfPCell pdfCell = new PdfPCell();
                    for (IBodyElement cellElement : cellElements) {
                        for (Element pdfEle : buildPdfElement(cellElement, listIndexMap)) {
                            pdfCell.addElement(pdfEle);
                        }
                    }
                    if (row.getHeight() > 0) {
                        pdfCell.setMinimumHeight(row.getHeight() / 1440f * 80);
                    }
                    pdfTable.addCell(pdfCell);
                }
            }
            res.add(pdfTable);
        } else if (element instanceof XWPFSDT) {
            //目录
            XWPFSDT xwpfsdt = (XWPFSDT) element;
            res.addAll(buildPdfElement(xwpfsdt));
        } else {
            //添加无法解析字段
            res.add(buildPdfParagraph("当前信息无法解析，请查看原件！"));
        }
        return res;
    }

    /**
     * 解析目录
     */
    private List<Element> buildPdfElement(XWPFSDT xwpfsdt) throws IOException, BadElementException {
        List<Element> res = new ArrayList<>();
        ISDTContent isdtContent = xwpfsdt.getContent();
        String contentStr = isdtContent.getText();
        String[] values = contentStr.split("\\n");
        for (String value : values) {
            String[] vs = value.split("\\t");
            if (vs.length == 1) {
                //构建标题
                Paragraph pdfParagraph = new Paragraph();
                pdfParagraph.setAlignment(Element.ALIGN_LEFT);
                pdfParagraph.setMultipliedLeading(1.0F);
                Font font = new Font(PDF_FONT);
                String style = "";
                //加粗
                style += Font.FontStyle.BOLD.getValue();
                font.setStyle(style);
                Chunk t = new Chunk(vs[0], font);
                pdfParagraph.add(t);
                pdfParagraph.setFont(new Font(PDF_FONT, (float)18));
                res.add(pdfParagraph);
            } else if (vs.length > 1) {
                //构建目录
                Paragraph pdfParagraph = new Paragraph();
                pdfParagraph.setAlignment(Element.ALIGN_LEFT);
                pdfParagraph.setMultipliedLeading(1.0F);
                //缩进
                pdfParagraph.setFirstLineIndent(20 * 1.33F);
                Font font = new Font(PDF_FONT);
                float textWidth = 0;
                Chunk lastChunk = null;
                for (int i = 0; i < vs.length; i++) {
                    String str = vs[i];
                    if (i < vs.length - 1) {
                        Chunk t = new Chunk(str, font);
                        pdfParagraph.add(t);
                        textWidth += t.getWidthPoint();
                    } else {
                        lastChunk = new Chunk(str, font);
                        textWidth += lastChunk.getWidthPoint();
                    }
                }
                int pointNum = (int)((280 - textWidth) / 3.336);
                StringBuilder tValue = new StringBuilder();
                for (int i = 0; i < pointNum; i++) {
                    tValue.append(".");
                }
                pdfParagraph.add(new Chunk(tValue.toString()));
                pdfParagraph.add(lastChunk);
                pdfParagraph.setFont(new Font(PDF_FONT, 14));
                res.add(pdfParagraph);
            }
        }
        return res;
    }

    private Paragraph buildPdfParagraph(XWPFParagraph paragraph) throws IOException, BadElementException {
        return buildPdfParagraph(paragraph, "");
    }

    private Paragraph buildPdfParagraph(XWPFParagraph paragraph, String prevStr) throws IOException, BadElementException {
        Paragraph pdfParagraph = new Paragraph();
        double maxFontSize = 14;
        //对齐方式
        ParagraphAlignment alignment = paragraph.getAlignment();
        if (ParagraphAlignment.LEFT == alignment) { //左对齐
            pdfParagraph.setAlignment(Element.ALIGN_LEFT);
        } else if (ParagraphAlignment.CENTER == alignment) { //居中对齐
            pdfParagraph.setAlignment(Element.ALIGN_CENTER);
        } else if (ParagraphAlignment.RIGHT == alignment) { //右对齐
            pdfParagraph.setAlignment(Element.ALIGN_RIGHT);
        } else { //左右对齐
            pdfParagraph.setAlignment(Element.ALIGN_LEFT);
        }
        //缩进
        pdfParagraph.setFirstLineIndent(paragraph.getFirstLineIndent() / 20 * 1.33F);
        //段前距离
        int spacingBefore = paragraph.getSpacingBefore();
        if (spacingBefore == -1) {
            pdfParagraph.setSpacingBefore(2 * 1.33F);
        } else {
            pdfParagraph.setSpacingBefore((spacingBefore/ 20F) + 2 * 1.33F);
        }
        //段后距离
        int spacingAfter = paragraph.getSpacingAfter();
        if (spacingAfter == -1) {
            pdfParagraph.setSpacingAfter(2 * 1.33F);
        } else {
            pdfParagraph.setSpacingAfter((spacingAfter/ 20F) + 2 * 1.33F);
        }
        //行距
        if (paragraph.getSpacingBetween() > 0) {
            pdfParagraph.setMultipliedLeading((float)paragraph.getSpacingBetween());
        } else {
            pdfParagraph.setMultipliedLeading(1.0F);
        }
        //遍历添加文字
        for (XWPFRun characterRun : paragraph.getRuns()) {
            Font font = new Font(PDF_FONT);
            if (characterRun.text() != null) {
                //字体颜色
                if (characterRun.getColor() != null && characterRun.getColor().length() == 6) {
                    font.setColor(
                            Integer.parseInt(characterRun.getColor().substring(0, 2), 16),
                            Integer.parseInt(characterRun.getColor().substring(2, 4), 16),
                            Integer.parseInt(characterRun.getColor().substring(4, 6), 16)
                    );
                }
                //字体大小
                if (characterRun.getFontSizeAsDouble() != null) {
                    font.setSize(characterRun.getFontSizeAsDouble().floatValue());
                    if (characterRun.getFontSizeAsDouble() > maxFontSize) {
                        maxFontSize = characterRun.getFontSizeAsDouble();
                    }
                }
                String style = "";
                //是否加粗
                if (characterRun.isBold()) {
                    style += Font.FontStyle.BOLD.getValue();
                }
                //是否斜字体
                if (characterRun.isItalic()) {
                    style += Font.FontStyle.ITALIC.getValue();
                }
                font.setStyle(style);
                if (prevStr != null) {
                    pdfParagraph.add(new Chunk(prevStr, font));
                    prevStr = null;
                }
                Chunk t = new Chunk(characterRun.text(), font);
                pdfParagraph.add(t);
            } else {
                if (prevStr != null) {
                    pdfParagraph.add(new Chunk(prevStr, font));
                    prevStr = null;
                }
            }
            //遍历图片
            for (XWPFPicture picture : characterRun.getEmbeddedPictures()) {
                double width = picture.getWidth();
                double depth = picture.getDepth();
                XWPFPictureData pictureData = picture.getPictureData();

                Image img = Image.getInstance(pictureData.getData());
                img.scaleAbsolute((float)width,
                        (float)depth);
                Chunk chunk = new Chunk(img, 0, 0, true);
                pdfParagraph.add(chunk);
            }
        }
        if (paragraph.getText() == null || paragraph.getText().length() == 0) {
            pdfParagraph.add(new Chunk("\r\n"));
        }
        pdfParagraph.setFont(new Font(PDF_FONT, (float)maxFontSize));
        return pdfParagraph;
    }

    private Paragraph buildPdfParagraph(String text) throws IOException, BadElementException {
        Paragraph pdfParagraph = new Paragraph();
        double maxFontSize = 14;
        pdfParagraph.setAlignment(Element.ALIGN_LEFT);
        pdfParagraph.setMultipliedLeading(1.0F);
        Font font = new Font(PDF_FONT);
        Chunk t = new Chunk(text, font);
        pdfParagraph.add(t);
        pdfParagraph.setFont(new Font(PDF_FONT, (float)maxFontSize));
        return pdfParagraph;
    }

}
